package org.amse.Archiver.algorithm;
import java.io.*;

public class DataCoderStream implements ICoder {
    private final DataOutputStream myOutputFile;
    private final DataInputStream myInputFile;
    private String myName;
	private byte[][] myCodeArray;
	private int myBitNum;
	private int mySymNum;
	private File output;
	private int [] myStatistic;
	public DataCoderStream(File input, byte[][] codeArray, int statistic[], int size) throws IOException {
	    myCodeArray = codeArray;
		myInputFile = new DataInputStream(new FileInputStream(input));
		output = new File(getNewName(input) + ".huf");
		myOutputFile = new DataOutputStream(new FileOutputStream(output));
		myStatistic = statistic;
        mySymNum = size;
        myName = input.getName();
	}
	
	public File getOutFile(){
		return output;
	}
	
    private String getNewName(File f){
		StringBuffer name = new StringBuffer();
		name.append(f.getAbsolutePath());
		name.delete(name.lastIndexOf("."), name.length());
    	return name.toString();
    }
    
	public void encode() throws IOException {
	    int ch;
		int tmp = 0;
		int curLen = 0;
		writeTechInf();
		while ((ch = myInputFile.read()) != -1) {
		    int i = ch; int j = 0;
			
			while(myCodeArray[i][j] != -1) {
			    int bit = myCodeArray[i][j++];
				bit =  bit << (7-curLen);
				tmp = tmp | bit;
				curLen++;
                
				if (curLen == 8) {
				    myOutputFile.write((byte)tmp);
					tmp = 0;
					curLen = 0;
				}
			}
		}
        if(curLen != 0){
            myOutputFile.write((byte)tmp);
        }
		myOutputFile.close();
	}
	
     public void writeTechInf() throws IOException {
		myOutputFile.writeUTF(myName);
    	 for (int i = 0; i < myStatistic.length; i++){
			int j = 0;
			int codeLength = 0;
			while(myCodeArray[i][j++] != -1) {                                                                                                                                                                                                                                                                                                                                                                
				codeLength = j;
			}
			myBitNum = (myBitNum + myStatistic[i]*codeLength) % 8;
		}       
		myOutputFile.writeInt(mySymNum);
		for (int i = 0; i < myStatistic.length; i++) {
		    myOutputFile.writeInt(myStatistic[i]);
		}
	 }
}